package com.example.a_java.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.a_java.common.BusinessException;
import com.example.a_java.common.ResultCode;
import com.example.a_java.dto.LoginDTO;
import com.example.a_java.dto.PasswordUpdateDTO;
import com.example.a_java.dto.RegisterDTO;
import com.example.a_java.dto.UserInfoDTO;
import com.example.a_java.dto.UserProfileUpdateDTO;
import com.example.a_java.entity.SysUser;
import com.example.a_java.mapper.SysRoleMapper;
import com.example.a_java.mapper.SysUserMapper;
import com.example.a_java.service.AuthService;
import com.example.a_java.util.JwtTokenUtil;
import com.example.a_java.util.PasswordEncoder;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 认证服务实现类
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private SysUserMapper sysUserMapper;
    
    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    
    @Value("${jwt.tokenHead:Bearer}")
    private String tokenHead;

    @Override
    public Map<String, Object> login(LoginDTO loginDTO, HttpServletRequest request) {
        // 验证用户名和密码
        SysUser user = sysUserMapper.selectByUsername(loginDTO.getUsername());

        if (user == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "用户名或密码错误");
        }

        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "用户名或密码错误");
        }

        // 更新登录信息
        user.setLoginIp(request.getRemoteAddr());
        user.setLoginTime(LocalDateTime.now());
        sysUserMapper.updateById(user);

        // 生成token
        String token = jwtTokenUtil.generateToken(user.getUsername());
        
        // 获取用户信息
        UserInfoDTO userInfo = getUserInfo(user.getUsername());
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("tokenHead", tokenHead);
        result.put("userInfo", userInfo);
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(RegisterDTO registerDTO) {
        // 验证用户名是否已存在
        SysUser existUser = sysUserMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, registerDTO.getUsername())
                        .last("LIMIT 1")
        );

        if (existUser != null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "用户名已存在");
        }

        // 验证两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "两次密码不一致");
        }

        // 创建用户
        SysUser user = new SysUser();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
        user.setRealName(registerDTO.getRealName());
        user.setMobile(registerDTO.getMobile());
        user.setEmail(registerDTO.getEmail());
        user.setStatus(1);
        user.setCreateTime(LocalDateTime.now());

        return sysUserMapper.insert(user) > 0;
    }

    @Override
    public void logout(HttpServletRequest request) {
        // 由于使用JWT，服务端不需要额外处理
        // 客户端只需要删除token即可
    }

    @Override
    public UserInfoDTO getUserInfo(String username) {
        // 获取用户基本信息
        SysUser user = sysUserMapper.selectByUsername(username);
        if (user == null) {
            throw new BusinessException(ResultCode.UNAUTHORIZED.getCode(), "用户不存在或已被禁用");
        }

        // 转换为DTO
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        BeanUtils.copyProperties(user, userInfoDTO);
        
        // 获取部门名称
        if (user.getDeptId() != null) {
            String deptName = sysUserMapper.selectDeptNameById(user.getDeptId());
            userInfoDTO.setDeptName(deptName);
        }
        
        // 获取用户角色和权限
        List<String> roles = sysRoleMapper.selectRoleKeysByUserId(user.getUserId());
        userInfoDTO.setRoles(roles);

        return userInfoDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePassword(PasswordUpdateDTO passwordUpdateDTO, String username) {
        // 验证用户是否存在
        SysUser user = sysUserMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
                        .eq(SysUser::getStatus, 1)
                        .last("LIMIT 1")
        );

        if (user == null) {
            throw new BusinessException(ResultCode.UNAUTHORIZED.getCode(), "用户不存在或已被禁用");
        }

        // 验证旧密码
        if (!passwordEncoder.matches(passwordUpdateDTO.getOldPassword(), user.getPassword())) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "旧密码错误");
        }

        // 验证两次密码是否一致
        if (!passwordUpdateDTO.getNewPassword().equals(passwordUpdateDTO.getConfirmPassword())) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "两次密码不一致");
        }

        // 更新密码
        user.setPassword(passwordEncoder.encode(passwordUpdateDTO.getNewPassword()));
        user.setUpdateTime(LocalDateTime.now());

        return sysUserMapper.updateById(user) > 0;
    }

    @Override
    public String refreshToken(String oldToken) {
        if (!StringUtils.hasText(oldToken)) {
            throw new BusinessException(ResultCode.UNAUTHORIZED.getCode(), "token不能为空");
        }

        String token = oldToken;
        // 如果token包含前缀，则去掉前缀
        if (token.startsWith(tokenHead)) {
            token = token.substring(tokenHead.length()).trim();
        }

        // 从token中获取用户名
        String username = jwtTokenUtil.getUsernameFromToken(token);
        if (!StringUtils.hasText(username)) {
            throw new BusinessException(ResultCode.UNAUTHORIZED.getCode(), "token已过期或无效");
        }

        // 验证用户是否存在
        SysUser user = sysUserMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
                        .eq(SysUser::getStatus, 1)
                        .last("LIMIT 1")
        );

        if (user == null) {
            throw new BusinessException(ResultCode.UNAUTHORIZED.getCode(), "用户不存在或已被禁用");
        }

        // 生成新token
        return jwtTokenUtil.generateToken(username);
    }

    @Override
    public String getUsernameFromToken(String token) {
        return jwtTokenUtil.getUsernameFromToken(token);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoDTO updateProfile(UserProfileUpdateDTO profileUpdateDTO, String username) {
        // 验证用户是否存在
        SysUser user = sysUserMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
                        .eq(SysUser::getStatus, 1)
                        .last("LIMIT 1")
        );

        if (user == null) {
            throw new BusinessException(ResultCode.UNAUTHORIZED.getCode(), "用户不存在或已被禁用");
        }

        // 更新用户信息
        if (profileUpdateDTO.getRealName() != null) {
            user.setRealName(profileUpdateDTO.getRealName());
        }
        if (profileUpdateDTO.getMobile() != null) {
            user.setMobile(profileUpdateDTO.getMobile());
        }
        if (profileUpdateDTO.getEmail() != null) {
            user.setEmail(profileUpdateDTO.getEmail());
        }
        if (profileUpdateDTO.getAvatar() != null) {
            user.setAvatar(profileUpdateDTO.getAvatar());
        }
        if (profileUpdateDTO.getDeptId() != null) {
            user.setDeptId(profileUpdateDTO.getDeptId());
        }
        if (profileUpdateDTO.getPositionId() != null) {
            user.setPositionId(profileUpdateDTO.getPositionId());
        }
        user.setUpdateTime(LocalDateTime.now());

        sysUserMapper.updateById(user);

        // 返回更新后的用户信息
        return getUserInfo(username);
    }
    
    @Override
    public List<String> getUserAuthorities(String username) {
        // 验证用户是否存在
        SysUser user = sysUserMapper.selectByUsername(username);
        if (user == null) {
            return new ArrayList<>();
        }
        
        // 对于admin用户，从数据库获取所有可用权限
        if ("admin".equals(username)) {
            try {
                // 首先尝试从数据库获取admin用户的权限
                List<String> permissions = sysRoleMapper.selectPermissionsByUserId(user.getUserId());
                
                if (permissions == null || permissions.isEmpty()) {
                    // 如果数据库中没有配置权限，则提供一组基本权限作为应急措施
                    List<String> adminPermissions = new ArrayList<>();
                    adminPermissions.add("account:list");
                    adminPermissions.add("account:create");
                    adminPermissions.add("account:query");
                    adminPermissions.add("account:deposit");
                    adminPermissions.add("account:withdraw");
                    adminPermissions.add("account:freeze");
                    adminPermissions.add("account:unfreeze");
                    adminPermissions.add("account:freezeAmount");
                    adminPermissions.add("account:unfreezeAmount");
                    adminPermissions.add("loan:apply:list");
                    adminPermissions.add("loan:apply:query");
                    adminPermissions.add("loan:apply:create");
                    adminPermissions.add("loan:apply:update");
                    adminPermissions.add("loan:apply:delete");
                    adminPermissions.add("loan:approval:list");
                    adminPermissions.add("loan:approval:submit");
                    adminPermissions.add("loan:approval:history");
                    adminPermissions.add("lending:list");
                    adminPermissions.add("lending:query");
                    adminPermissions.add("lending:apply");
                    adminPermissions.add("lending:process");
                    adminPermissions.add("lending:approval");
                    adminPermissions.add("system:user");
                    adminPermissions.add("system:role");
                    adminPermissions.add("system:permission");
                    return adminPermissions;
                }
            } catch (Exception e) {
                // 发生异常时提供一组基本权限作为应急措施
                List<String> adminPermissions = new ArrayList<>();
                adminPermissions.add("account:list");
                adminPermissions.add("account:create");
                adminPermissions.add("account:query");
                // 添加其他基本权限...
                return adminPermissions;
            }
        }
        
        // 获取普通用户权限
        try {
            List<String> authorities = sysRoleMapper.selectPermissionsByUserId(user.getUserId());
            
            // 如果没有获取到权限信息，则返回空列表
            if (authorities == null) {
                return new ArrayList<>();
            }
            
            return authorities;
        } catch (Exception e) {
            // 发生异常时记录日志并返回空列表
            System.err.println("获取用户权限时发生错误: " + e.getMessage());
            return new ArrayList<>();
        }
    }
} 
